package com.hooper.login.aop;

import com.hooper.login.anno.AuthCheck;
import com.hooper.login.entity.Roles;
import com.hooper.login.entity.UserDto;
import com.hooper.login.exception.BusinessException;
import com.hooper.login.util.UserHolder;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.Arrays;

/**
 * @author Tim Hooper
 * @version 1.0
 * @time 2022/12/28/15:23
 */
@Aspect
@Component
public class AuthorizationCheckAspect {

    @Around("@annotation(authCheck)")
    public Object doCheck(ProceedingJoinPoint joinPoint, AuthCheck authCheck) throws Throwable {
        UserDto userDto = UserHolder.getUser();
        System.out.println(userDto);
        if (userDto == null) {
            throw new BusinessException("未登录！");
        }

        String userRole = userDto.getRole();
        //是管理员则直接通过
        if (userRole.equals(Roles.ADMIN.getRole())) {
            return joinPoint.proceed();
        }

        //若必须为管理员才能执行则直接抛异常
        if (authCheck.isAdmin()) {
            throw new BusinessException("没有权限执行!");
        }

        Roles[] allowRoles = authCheck.allowRoles();
        boolean matchAllow = Arrays.stream(allowRoles).map(Roles::getRole).anyMatch(role -> role.equals(userRole));
        //判断是否在允许的角色权限中
        if (matchAllow) return joinPoint.proceed();

        Roles[] exceptRoles = authCheck.exceptRoles();
        boolean matchExcept = Arrays.stream(exceptRoles).map(Roles::getRole).anyMatch(role -> role.equals(userRole));
        if (matchExcept) {
            throw new BusinessException("没有权限执行!");
        }
        if (allowRoles.length != 0) throw new BusinessException("没有权限执行!");
        return joinPoint.proceed();
    }
}
